// import com.alibaba.druid.sql.SQLUtils;
// import com.alibaba.druid.sql.ast.SQLName;
// import com.alibaba.druid.sql.ast.SQLObject;
// import com.alibaba.druid.sql.ast.statement.SQLColumnDefinition;
// import com.alibaba.druid.sql.dialect.mysql.visitor.MySqlASTVisitor;
// import com.alibaba.druid.util.FnvHash;

// import java.util.Collections;
// import java.util.List;

#include "MySqlUserName.h"
#include "../../../../ast/SQLObject.h"
#include "../../visitor/MySqlASTVisitor.h"
#include "../../../../../utils/FnvHash.h"
#include "../../../../SQLUtils.h"

string_ptr MySqlUserName::getUserName()
{
  return userName;
}

void MySqlUserName::setUserName(string_ptr userName)
{
  this->userName = userName;

  this->hashCode64_ = 0;
  this->userNameHashCod64 = 0;
}

string_ptr MySqlUserName::getNormalizeUserName()
{
  return SQLUtils::normalize(userName);
}

string_ptr MySqlUserName::getHost()
{
  return host;
}

void MySqlUserName::setHost(string_ptr host)
{
  this->host = host;

  this->hashCode64_ = 0;
  this->userNameHashCod64 = 0;
}

// @Override
void MySqlUserName::accept0(MySqlASTVisitor_ptr visitor)
{
  visitor->visit(SharedObject(MySqlUserName));
  visitor->endVisit(SharedObject(MySqlUserName));
}

string_ptr MySqlUserName::getSimpleName()
{
  std::string buf = "";

  if (userName->length() == 0 || userName->at(0) != '\'')
  {
    buf += '\'';
    buf += userName->c_str();
    buf += '\'';
  }
  else
  {
    buf += userName->c_str();
  }

  buf += '@';

  if (host->length() == 0 || host->at(0) != '\'')
  {
    buf += '\'';
    buf += host->c_str();
    buf += '\'';
  }
  else
  {
    buf += host->c_str();
  }

  if (identifiedBy != nullptr)
  {
    buf += " identifiedBy by ";
    buf += identifiedBy->c_str();
  }

  return make_string_ptr(buf);
}

string_ptr MySqlUserName::getIdentifiedBy()
{
  return identifiedBy;
}

void MySqlUserName::setIdentifiedBy(string_ptr identifiedBy)
{
  this->identifiedBy = identifiedBy;
}

string_ptr MySqlUserName::toString()
{
  return getSimpleName();
}

SQLObject_ptr MySqlUserName::clone()
{
  SQLObject_ptr clone_tmp = std::shared_ptr<MySqlUserName>(new MySqlUserName());
  std::shared_ptr<MySqlUserName> x = std::dynamic_pointer_cast<MySqlUserName>(clone_tmp);
  // MySqlUserName x = new MySqlUserName();

  x->userName = userName;
  x->host = host;
  x->identifiedBy = identifiedBy;
  x->hashCode64_ = hashCode64_;
  x->userNameHashCod64 = userNameHashCod64;

  return x;
}

// @Override
SQLObject_list_ptr MySqlUserName::getChildren()
{
  SQLObject_list_ptr tmp = std::make_shared<std::list<SQLObject_ptr>>();
  return tmp;
}

long MySqlUserName::nameHashCode64()
{
  if (userNameHashCod64 == 0 && userName != nullptr)
  {
    userNameHashCod64 = FnvHash::hashCode64(userName);
  }
  return userNameHashCod64;
}

// @Override
long MySqlUserName::hashCode64()
{
  if (hashCode64_ == 0)
  {
    if (host != nullptr)
    {
      long hash = FnvHash::hashCode64(host);
      hash ^= '@';
      hash *= 0x100000001b3L;
      hash = FnvHash::hashCode64(hash, userName);

      hashCode64_ = hash;
    }
    else
    {
      hashCode64_ = nameHashCode64();
    }
  }

  return hashCode64_;
}

// @Override
SQLObject_ptr MySqlUserName::getResolvedColumn()
{
  return nullptr;
}
